//第一步项目GULP根目录创建gulpfile.js配置文件
//npm init -y; npm install gulp-cli -g; npm install gulp -D
//gulp -v CLI version:2.3.0 local version:4.0.2
let { parallel, series, src, pipe, dest, watch } = require('gulp');
var browserSync = require('browser-sync'); //实现浏览器自动刷新和热更新
let del = require('del'); // 删除文件夹和文件
let rename = require('gulp-rename'); //重命名
const htmlmin = require('gulp-htmlmin'); //html压缩
let sass = require('gulp-sass')(require('sass')); //css
const autoprefixer = require('gulp-autoprefixer');//使用Autoprefixer前缀 CSS,autoprefixer仅仅postcss工具中的一个小插件
const cssmin = require('gulp-cssmin'); // css压缩
var concat = require('gulp-concat'); // 合并js和css
const uglify = require('gulp-uglify'); //js压缩
var babel = require('gulp-babel'); // babel把es6变为es5

// 清除构建目录cleandist 
function cleandist() {
    return del(['./dist/']);
}
// src目录下的文件复制到dist文件
// pipe():管道方法。
//dest():将数据写入目标目录dist
// 方法顺序先src(原路径)=>pipe1=>pipe2=>pipe3=>pipe(dest(目标的路径:./dist))

//压缩html
function minhtml() {
    return src('./src/index.html')//读入文件产生数据流。gulp.src()路径匹配。!是排除操作，例如src(['**/*.js', '!node_modules/'])
        .pipe(htmlmin({ 
            collapseWhitespace: true,//去掉空格
            removeComments:true  //去掉注释
         }))
        .pipe(dest('./dist'))
}

//scss编译css 步骤：scss->css->合并css->压缩->重命名->dist/css
//压缩css
function mincss() {
    return src('./src/scss/*.scss')
        .pipe(sass()) //编译sass()
        .pipe(autoprefixer({ //Autoprefixer添加前缀 CSS 浏览器版本
            browsers: ['last 2 versions'],
        }))
        //css压缩和重命名
        .pipe(cssmin())
        .pipe(rename({//rename重命名
            suffix: ".min"//suffix:后缀
        }))
        .pipe(dest('dist/css/'))
        .pipe(browserSync.stream()) //同步浏览器
}
// 合并所有js
function minjs() {
    return src('./src/js/*.js')//匹配js(src)目录下所有后缀名为js(sonjs)的文件
        .pipe(concat('all.js'))//合并所有js后缀为all.js
        //把es6变成es5
        // npm install --save-dev gulp-babel @babel/core @babel/preset-env
        .pipe(babel(
            {
                presets: ['@babel/preset-env']
            }
        ))
        .pipe(uglify())//uglify js压缩
        .pipe(dest('./dist/js/'))
        //stream方法返回一个变换流，并且可以充当一次或多个文件。
        .pipe(browserSync.stream()) //同步浏览器，热更新。browser-sync插件 , 核心是在最后的操作，把最终处理的流数据同步给浏览器
}
// 监听scss、css、js文件改变，自动触发js和css
function watchfrontend() {
    //开启服务器并指定网站的根目录，热更新初始化
    // 启动browsersync服务，这将启动服务器，代理服务器或静态服务器，这取决你实际需要。
    browserSync.init({
        server: "./dist"
    })
    //watch监听文件的改变自动执行任务
    //reload方法会通知所有的浏览器相关文件被改动，要么导致浏览器刷新，要么注入文件，实时更新改动。
    watch('./src/index.html', minhtml).on('change', browserSync.reload) // browserSync.reload热更新重装
    // 热更新
    watch('./src/scss/*.scss', mincss); //watch监听mincss
    watch('./src/js/*.js', minjs); //watch监听minjs
}
//exports.任务名 = 函数名 终端中输入以下命令执行任务：gulp 加 任务名
// 构建任务前需要删除原来的构建目录(src目录)，同步任务：先删除再构建任务
//(gulp serve)在服务器下面开发，可以实现页面的热更新，parallel并行执行多个任务，watchfrontend开发阶段才有
exports.serve = parallel(minhtml, mincss, minjs, watchfrontend)//开发阶段
// (gulp build)不用启动服务器，只要把构建好的文件部署到线上服务器 
//先删除dist目录，完毕之后，在并行(js)执行任务js和css，串联series执行多个任务
exports.build = series(cleandist, parallel(minhtml, mincss, minjs))//部署阶段
